home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-27 | 58.7 KB | 1,276 lines | [TEXT/ROSA] |
- Common Lisp the Language, 2nd Edition
- -------------------------------------------------------------------------------
-
- 5. Program Structure
-
- In chapter 2 the syntax was sketched for notating data objects in Common Lisp.
- The same syntax is used for notating programs because all Common Lisp programs
- have a representation as Common Lisp data objects.
-
- Lisp programs are organized as forms and functions. Forms are evaluated
- (relative to some context) to produce values and side effects. Functions are
- invoked by applying them to arguments. The most important kind of form performs
- a function call; conversely, a function performs computation by evaluating
- forms.
-
- In this chapter, forms are discussed first and then functions. Finally, certain
- ``top level'' special forms are discussed; the most important of these is
- defun, whose purpose is to define a named function.
-
- -------------------------------------------------------------------------------
-
- * Forms
- o Self-Evaluating Forms
- o Variables
- o Special Forms
- o Macros
- o Function Calls
- * Functions
- o Named Functions
- o Lambda-Expressions
- * Top-Level Forms
- o Defining Named Functions
- o Declaring Global Variables and Named Constants
- o Control of Time of Evaluation
-
- -------------------------------------------------------------------------------
-
-
- 5.1. Forms
-
- The standard unit of interaction with a Common Lisp implementation is the form,
- which is simply a data object meant to be evaluated as a program to produce one
- or more values (which are also data objects). One may request evaluation of any
- data object, but only certain ones are meaningful. For instance, symbols and
- lists are meaningful forms, while arrays normally are not. Examples of
- meaningful forms are 3, whose value is 3, and (+ 3 4), whose value is 7. We
- write 3 => 3 and (+ 3 4) => 7 to indicate these facts. (=> means ``evaluates
- to.'')
-
- Meaningful forms may be divided into three categories: self-evaluating forms,
- such as numbers; symbols, which stand for variables; and lists. The lists in
- turn may be divided into three categories: special forms, macro calls, and
- function calls.
-
- [old_change_begin]
- Any Common Lisp data object not explicitly defined here to be a valid form is
- not a valid form. It is an error to evaluate anything but a valid form.
-
- -------------------------------------------------------------------------------
- Implementation note: An implementation is free to make implementation-dependent
- extensions to the evaluator but is strongly encouraged to signal an error on
- any attempt to evaluate anything but a valid form or an object for which a
- meaningful evaluation extension has been purposely defined.
- -------------------------------------------------------------------------------
-
- [old_change_end]
-
- [change_begin]
- X3J13 voted in October 1988 (EVAL-OTHER) to specify that all standard Common
- Lisp data objects other than symbols and lists (including defstruct structures
- defined without the :type option) are self-evaluating.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- * Self-Evaluating Forms
- * Variables
- * Special Forms
- * Macros
- * Function Calls
-
- -------------------------------------------------------------------------------
-
-
- 5.1.1. Self-Evaluating Forms
-
- All numbers, characters, strings, and bit-vectors are self-evaluating forms.
- When such an object is evaluated, that object (or possibly a copy in the case
- of numbers or characters) is returned as the value of the form. The empty list
- (), which is also the false value nil, is also a self-evaluating form: the
- value of nil is nil. Keywords (symbols written with a leading colon) also
- evaluate to themselves: the value of :start is :start.
-
- [change_begin]
- X3J13 voted in January 1989 (CONSTANT-MODIFICATION) to clarify that it is an
- error to destructively modify any object that appears as a constant in
- executable code, whether as a self-evaluating form or within a quote special
- form.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 5.1.2. Variables
-
- Symbols are used as names of variables in Common Lisp programs. When a symbol
- is evaluated as a form, the value of the variable it names is produced. For
- example, after doing (setq items 3), which assigns the value 3 to the variable
- named items, then items => 3. Variables can be assigned to, as by setq, or
- bound, as by let. Any program construct that binds a variable effectively saves
- the old value of the variable and causes it to have a new value, and on exit
- from the construct the old value is reinstated.
-
- There are actually two kinds of variables in Common Lisp, called lexical (or
- static) variables and special (or dynamic) variables. At any given time either
- or both kinds of variable with the same name may have a current value. Which of
- the two kinds of variable is referred to when a symbol is evaluated depends on
- the context of the evaluation. The general rule is that if the symbol occurs
- textually within a program construct that creates a binding for a variable of
- the same name, then the reference is to the variable specified by the binding;
- if no such program construct textually contains the reference, then it is taken
- to refer to the special variable of that name.
-
- The distinction between the two kinds of variable is one of scope and extent. A
- lexically bound variable can be referred to only by forms occurring at any
- place textually within the program construct that binds the variable. A
- dynamically bound (special) variable can be referred to at any time from the
- time the binding is made until the time evaluation of the construct that binds
- the variable terminates. Therefore lexical binding of variables imposes a
- spatial limitation on occurrences of references (but no temporal limitation,
- for the binding continues to exist as long as the possibility of reference
- remains). Conversely, dynamic binding of variables imposes a temporal
- limitation on occurrences of references (but no spatial limitation). For more
- information on scope and extent, see chapter 3.
-
- The value a special variable has when there are currently no bindings of that
- variable is called the global value of the (special) variable. A global value
- can be given to a variable only by assignment, because a value given by binding
- is by definition not global.
-
- It is possible for a special variable to have no value at all, in which case it
- is said to be unbound. By default, every global variable is unbound unless and
- until explicitly assigned a value, except for those global variables defined in
- this book or by the implementation already to have values when the Lisp system
- is first started. It is also possible to establish a binding of a special
- variable and then cause that binding to be valueless by using the function
- makunbound. In this situation the variable is also said to be ``unbound,''
- although this is a misnomer; precisely speaking, it is bound but valueless. It
- is an error to refer to a variable that is unbound.
-
- [change_begin]
- X3J13 voted in June 1989 (UNDEFINED-VARIABLES-AND-FUNCTIONS) to specify more
- precisely the effects of referring to an unbound variable.
-
- Reading an unbound variable or an undefined function must be detected in the
- highest safety setting (see the safety quality of the optimize declaration
- specifier) but the effect is undefined in any other safety setting. That is,
- reading an unbound variable should signal an error and reading an undefined
- function should signal an error. (``Reading a function'' includes both
- references to the function using the function special form, such as f in
- (function f), and references to the function in a call, such as f in (f x y).)
-
- For the case of inline functions (in implementations where they are supported),
- a permitted point of view is that performing the inlining constitutes the read
- of the function, so that an fboundp check need not be done at execution time.
- Put another way, the effect of the application of fmakunbound to a function
- name on potentially inlined references to that function is undefined.
-
- When an unbound variable is detected an error of type unbound-variable is
- signaled, and the name slot of the unbound-variable condition is initialized to
- the name of the offending variable.
-
- When an undefined function is detected an error of type undefined-function is
- signaled, and the name slot of the undefined-function condition is initialized
- to the name of the offending function.
-
- The condition type unbound-slot, which inherits from cell-error, has an
- additional slot instance, which can be initialized using the :instance keyword
- to make-condition. The function unbound-slot-instance accesses this slot.
-
- The type of error signaled by the default primary method for the CLOS
- slot-unbound generic function is unbound-slot. The instance slot of the
- unbound-slot condition is initialized to the offending instance and the name
- slot is initialized to the name of the offending variable.
- [change_end]
-
- Certain global variables are reserved as ``named constants.'' They have a
- global value and may not be bound or assigned to. For example, the symbols t
- and nil are reserved. One may not assign a value to t or nil, and one may not
- bind t or nil. The global value of t is always t, and the global value of nil
- is always nil. Constant symbols defined by defconstant also become reserved and
- may not be further assigned to or bound (although they may be redefined, if
- necessary, by using defconstant again). Keyword symbols, which are notated with
- a leading colon, are reserved and may never be assigned to or bound; a keyword
- always evaluates to itself.
-
- -------------------------------------------------------------------------------
-
- 5.1.3. Special Forms
-
- If a list is to be evaluated as a form, the first step is to examine the first
- element of the list. If the first element is one of the symbols appearing in
- table 5-1, then the list is called a special form. (This use of the word
- ``special'' is unrelated to its use in the phrase ``special variable.'')
-
- Special forms are generally environment and control constructs. Every special
- form has its own idiosyncratic syntax. An example is the if special form: (if p
- (+ x 4) 5) in Common Lisp means what ``if p then x+4 else 5'' means in Algol.
-
- The evaluation of a special form normally produces a value or values, but the
- evaluation may instead call for a non-local exit; see return-from, go, and
- throw.
-
- The set of special forms is fixed in Common Lisp; no way is provided for the
- user to define more. The user can create new syntactic constructs, however, by
- defining macros.
-
- The set of special forms in Common Lisp is purposely kept very small because
- any program-analyzing program must have special knowledge about every type of
- special form. Such a program needs no special knowledge about macros because it
- is simple to expand the macro and operate on the resulting expansion. (This is
- not to say that many such programs, particularly compilers, will not have such
- special knowledge. A compiler may be able to produce much better code if it
- recognizes such constructs as typecase and multiple-value-bind and gives them
- customized treatment.)
-
-
-
- An implementation is free to implement as a macro any construct described
- herein as a special form. Conversely, an implementation is free to implement as
- a special form any construct described herein as a macro if an equivalent macro
- definition is also provided. The practical consequence is that the predicates
- macro-function and special-form-p may both be true of the same symbol. It is
- recommended that a program-analyzing program process a form that is a list
- whose car is a symbol as follows:
-
- 1. If the program has particular knowledge about the symbol, process the
- form using special-purpose code. All of the symbols listed in table 5-1
- should fall into this category.
-
- 2. Otherwise, if macro-function is true of the symbol, apply either
- macroexpand or macroexpand-1, as appropriate, to the entire form and then
- start over.
-
- 3. Otherwise, assume it is a function call.
-
- -------------------------------------------------------------------------------
-
- 5.1.4. Macros
-
- If a form is a list and the first element is not the name of a special form, it
- may be the name of a macro; if so, the form is said to be a macro call. A macro
- is essentially a function from forms to forms that will, given a call to that
- macro, compute a new form to be evaluated in place of the macro call. (This
- computation is sometimes referred to as macro expansion.) For example, the
- macro named return will take a form such as (return x) and from that form
- compute a new form (return-from nil x). We say that the old form expands into
- the new form. The new form is then evaluated in place of the original form; the
- value of the new form is returned as the value of the original form.
-
- [change_begin]
- X3J13 voted in January 1989 (DOTTED-MACRO-FORMS) to clarify that macro calls,
- and subforms of macro calls, need not be proper lists, but that use of dotted
- forms requires the macro definition to use ``. var'' or ``&rest var'' in order
- to match them properly. It is then the responsibility of the macro definition
- to recognize and appropriately handle such dotted forms or subforms.
- [change_end]
-
- There are a number of standard macros in Common Lisp, and the user can define
- more by using defmacro.
-
- Macros provided by a Common Lisp implementation as described herein may expand
- into code that is not portable among differing implementations. That is, a
- macro call may be implementation-independent because the macro is defined in
- this book, but the expansion need not be.
-
- -------------------------------------------------------------------------------
- Implementation note: Implementors are encouraged to implement the macros
- defined in this book, as far as is possible, in such a way that the expansion
- will not contain any implementation-dependent special forms, nor contain as
- forms data objects that are not considered to be forms in Common Lisp. The
- purpose of this restriction is to ensure that the expansion can be processed by
- a program-analyzing program in an implementation-independent manner. There is
- no problem with a macro expansion containing calls to implementation-dependent
- functions. This restriction is not a requirement of Common Lisp; it is
- recognized that certain complex macros may be able to expand into significantly
- more efficient code in certain implementations by using
- implementation-dependent special forms in the macro expansion.
- -------------------------------------------------------------------------------
-
- 5.1.5. Function Calls
-
- If a list is to be evaluated as a form and the first element is not a symbol
- that names a special form or macro, then the list is assumed to be a function
- call. The first element of the list is taken to name a function. Any and all
- remaining elements of the list are forms to be evaluated; one value is obtained
- from each form, and these values become the arguments to the function. The
- function is then applied to the arguments. The functional computation normally
- produces a value, but it may instead call for a non-local exit; see throw. A
- function that does return may produce no value or several values; see values.
- If and when the function returns, whatever values it returns become the values
- of the function-call form.
-
- For example, consider the evaluation of the form (+ 3 (* 4 5)). The symbol +
- names the addition function, not a special form or macro. Therefore the two
- forms 3 and (* 4 5) are evaluated to produce arguments. The form 3 evaluates to
- 3, and the form (* 4 5) is a function call (to the multiplication function).
- Therefore the forms 4 and 5 are evaluated, producing arguments 4 and 5 for the
- multiplication. The multiplication function calculates the number 20 and
- returns it. The values 3 and 20 are then given as arguments to the addition
- function, which calculates and returns the number 23. Therefore we say (+ 3 (*
- 4 5)) => 23.
-
- [change_begin]
- X3J13 voted in October 1988 (FUNCTION-CALL-EVALUATION-ORDER) to clarify that
- while the arguments in a function call are always evaluated in strict
- left-to-right order, whether the function to be called is determined before or
- after argument evaluation is unspecified. Programs are in error that rely on a
- particular order of evaluation of the first element of a function call relative
- to the argument forms.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 5.2. Functions
-
- There are two ways to indicate a function to be used in a function-call form.
- One is to use a symbol that names the function. This use of symbols to name
- functions is completely independent of their use in naming special and lexical
- variables. The other way is to use a lambda-expression, which is a list whose
- first element is the symbol lambda. A lambda-expression is not a form; it
- cannot be meaningfully evaluated. Lambda-expressions and symbols, when used in
- programs as names of functions, can appear only as the first element of a
- function-call form, or as the second element of the function special form. Note
- that symbols and lambda-expressions are treated as names of functions in these
- two contexts. This should be distinguished from the treatment of symbols and
- lambda-expressions as function objects, that is, objects that satisfy the
- predicate functionp, as when giving such an object to apply or funcall to be
- invoked.
-
- -------------------------------------------------------------------------------
-
- * Named Functions
- * Lambda-Expressions
-
- -------------------------------------------------------------------------------
-
- 5.2.1. Named Functions
-
- A name can be given to a function in one of two ways. A global name can be
- given to a function by using the defun construct. A local name can be given to
- a function by using the flet or labels special form. When a function is named,
- a lambda-expression is effectively associated with that name along with
- information about the entities that are lexically apparent at that point. If a
- symbol appears as the first element of a function-call form, then it refers to
- the definition established by the innermost flet or labels construct that
- textually contains the reference, or to the global definition (if any) if there
- is no such containing construct.
-
- -------------------------------------------------------------------------------
-
- 5.2.2. Lambda-Expressions
-
- A lambda-expression is a list with the following syntax:
-
- (lambda lambda-list . body)
-
- The first element must be the symbol lambda. The second element must be a list.
- It is called the lambda-list, and specifies names for the parameters of the
- function. When the function denoted by the lambda-expression is applied to
- arguments, the arguments are matched with the parameters specified by the
- lambda-list. The body may then refer to the arguments by using the parameter
- names. The body consists of any number of forms (possibly zero). These forms
- are evaluated in sequence, and the results of the last form only are returned
- as the results of the application (the value nil is returned if there are zero
- forms in the body). The complete syntax of a lambda-expression is:
-
- (lambda ({var}*
- [&optional {var | (var [initform [svar]])}*]
- [&rest var]
- [&key {var | ({var | (keyword var)} [initform [svar]])}*
- [&allow-other-keys]]
- [&aux {var | (var [initform])}*)]
- [[{declaration}* | documentation-string]]
- {form}*)
-
- Each element of a lambda-list is either a parameter specifier or a lambda-list
- keyword; lambda-list keywords begin with &. (Note that lambda-list keywords are
- not keywords in the usual sense; they do not belong to the keyword package.
- They are ordinary symbols each of whose names begins with an ampersand. This
- terminology is unfortunately confusing but is retained for historical reasons.)
-
- [old_change_begin]
- In all cases a var or svar must be a symbol, the name of a variable; each
- keyword must be a keyword symbol, such as :start. An initform may be any form.
- [old_change_end]
-
- [change_begin]
- X3J13 voted in March 1988 (KEYWORD-ARGUMENT-NAME-PACKAGE) to allow a keyword
- in the preceding specification of a lambda-list to be any symbol whatsoever,
- not just a keyword symbol in the keyword package. See below.
- [change_end]
-
- A lambda-list has five parts, any or all of which may be empty:
-
- * Specifiers for the required parameters. These are all the parameter
- specifiers up to the first lambda-list keyword; if there is no such
- lambda-list keyword, then all the specifiers are for required parameters.
-
- * Specifiers for optional parameters. If the lambda-list keyword &optional
- is present, the optional parameter specifiers are those following the
- lambda-list keyword &optional up to the next lambda-list keyword or the
- end of the list.
-
- * A specifier for a rest parameter. The lambda-list keyword &rest, if
- present, must be followed by a single rest parameter specifier, which in
- turn must be followed by another lambda-list keyword or the end of the
- lambda-list.
-
- * Specifiers for keyword parameters. If the lambda-list keyword &key is
- present, all specifiers up to the next lambda-list keyword or the end of
- the list are keyword parameter specifiers. The keyword parameter
- specifiers may optionally be followed by the lambda-list keyword
- &allow-other-keys.
-
- * Specifiers for aux variables. These are not really parameters. If the
- lambda-list keyword &key is present, all specifiers after it are auxiliary
- variable specifiers.
-
- When the function represented by the lambda-expression is applied to arguments,
- the arguments and parameters are processed in order from left to right. In the
- simplest case, only required parameters are present in the lambda-list; each is
- specified simply by a name var for the parameter variable. When the function is
- applied, there must be exactly as many arguments as there are parameters, and
- each parameter is bound to one argument. Here, and in general, the parameter is
- bound as a lexical variable unless a declaration has been made that it should
- be a special binding; see defvar, proclaim, and declare.
-
- In the more general case, if there are n required parameters (n may be zero),
- there must be at least n arguments, and the required parameters are bound to
- the first n arguments. The other parameters are then processed using any
- remaining arguments.
-
- If optional parameters are specified, then each one is processed as follows. If
- any unprocessed arguments remain, then the parameter variable var is bound to
- the next remaining argument, just as for a required parameter. If no arguments
- remain, however, then the initform part of the parameter specifier is
- evaluated, and the parameter variable is bound to the resulting value (or to
- nil if no initform appears in the parameter specifier). If another variable
- name svar appears in the specifier, it is bound to true if an argument was
- available, and to false if no argument remained (and therefore initform had to
- be evaluated). The variable svar is called a supplied-p parameter; it is bound
- not to an argument but to a value indicating whether or not an argument had
- been supplied for another parameter.
-
- After all optional parameter specifiers have been processed, then there may or
- may not be a rest parameter. If there is a rest parameter, it is bound to a
- list of all as-yet-unprocessed arguments. (If no unprocessed arguments remain,
- the rest parameter is bound to the empty list.) If there is no rest parameter
- and there are no keyword parameters, then there should be no unprocessed
- arguments (it is an error if there are).
-
- [change_begin]
- X3J13 voted in January 1989 (REST-LIST-ALLOCATION) to clarify that if a
- function has a rest parameter and is called using apply, then the list to which
- the rest parameter is bound is permitted, but not required, to share top-level
- list structure with the list that was the last argument to apply. Programmers
- should be careful about performing side effects on the top-level list structure
- of a rest parameter.
-
- This was the result of a rather long discussion within X3J13 and the wider Lisp
- community. To set it in its historical context, I must remark that in Lisp
- Machine Lisp the list to which a rest parameter was bound had only dynamic
- extent; this in conjunction with the technique of ``cdr-coding'' permitted a
- clever stack-allocation technique with very low overhead. However, the early
- designers of Common Lisp, after a great deal of debate, concluded that it was
- dangerous for cons cells to have dynamic extent; as an example, the ``obvious''
- definition of the function list
-
- (defun list (&rest x) x)
-
- could fail catastrophically. Therefore the first edition simply implied that
- the list for a rest parameter, like all other lists, would have indefinite
- extent. This still left open the flip side of the question, namely, Is the list
- for a rest parameter guaranteed fresh? This is the question addressed by the
- X3J13 vote. If it is always freshly consed, then it is permissible to destroy
- it, for example by giving it to nconc. However, the requirement always to cons
- fresh lists could impose an unacceptable overhead in many implementations. The
- clarification approved by X3J13 specifies that the programmer may not rely on
- the list being fresh; if the function was called using apply, there is no way
- to know where the list came from.
- [change_end]
-
- Next, any keyword parameters are processed. For this purpose the same arguments
- are processed that would be made into a list for a rest parameter. (Indeed, it
- is permitted to specify both &rest and &key. In this case the remaining
- arguments are used for both purposes; that is, all remaining arguments are made
- into a list for the &rest parameter and are also processed for the &key
- parameters. This is the only situation in which an argument is used in the
- processing of more than one parameter specifier.) If &key is specified, there
- must remain an even number of arguments; these are considered as pairs, the
- first argument in each pair being interpreted as a keyword name and the second
- as the corresponding value.
-
- [old_change_begin]
- It is an error for the first object of each pair to be anything but a keyword.
-
- -------------------------------------------------------------------------------
- Rationale: This last restriction is imposed so that a compiler may issue
- warnings about certain malformed calls to functions that take keyword
- arguments. It must be remembered that the arguments in a function call that
- evaluate to keywords are just like any other arguments and may be any evaluable
- forms. A compiler could not, without additional context, issue a warning about
- the call
-
- (fill seq item x y)
-
- because in principle the variable x might have as its value a keyword such as
- :start. However, a compiler would be justified in issuing a warning about the
- call
-
- (fill seq item 0 10)
-
- because the constant 0 is definitely not a keyword. Similarly, if in the first
- case the variable x had been declared to be of type integer, then type analysis
- could enable the compiler to justify a warning.
- -------------------------------------------------------------------------------
- [old_change_end]
-
- [change_begin]
- X3J13 voted in March 1988 (KEYWORD-ARGUMENT-NAME-PACKAGE) to allow a keyword
- in a lambda-list to be any symbol whatsoever, not just a keyword symbol in the
- keyword package. If, after &key, a variable appears alone or within only one
- set of parentheses (possibly with an initform and a svar), then the behavior is
- as before: a keyword symbol with the same name as the variable is used as the
- keyword-name when matching arguments to parameter specifiers. Only a parameter
- specifier of the form ((keyword var) ...) can cause the keyword-name not to be
- a keyword symbol, by specifying a symbol not in the keyword package as the
- keyword. For example:
-
- (defun wager (&key ((secret password) nil) amount)
- (format nil "You ~A $~D"
- (if (eq password 'joe-sent-me) "win" "lose")
- amount))
-
- (wager :amount 100) => "You lose $100"
- (wager :amount 100 'secret 'joe-sent-me) => "You win $100"
-
- The secret word could be made even more secret in this example by placing it in
- some other obscure package, so that one would have to write
-
- (wager :amount 100 'obscure:secret 'joe-sent-me) => "You win $100"
-
- to win anything.
- [change_end]
-
- In each keyword parameter specifier must be a name var for the parameter
- variable. If an explicit keyword is specified, then that is the keyword name
- for the parameter. Otherwise the name var serves to indicate the keyword name,
- in that a keyword with the same name (in the keyword package) is used as the
- keyword. Thus
-
- (defun foo (&key radix (type 'integer)) ...)
-
- means exactly the same as
-
- (defun foo (&key ((:radix radix)) ((:type type) 'integer)) ...)
-
- The keyword parameter specifiers are, like all parameter specifiers,
- effectively processed from left to right. For each keyword parameter specifier,
- if there is an argument pair whose keyword name matches that specifier's
- keyword name (that is, the names are eq), then the parameter variable for that
- specifier is bound to the second item (the value) of that argument pair. If
- more than one such argument pair matches, it is not an error; the leftmost
- argument pair is used. If no such argument pair exists, then the initform for
- that specifier is evaluated and the parameter variable is bound to that value
- (or to nil if no initform was specified). The variable svar is treated as for
- ordinary optional parameters: it is bound to true if there was a matching
- argument pair, and to false otherwise.
-
- It is an error if an argument pair has a keyword name not matched by any
- parameter specifier, unless at least one of the following two conditions is
- met:
-
- * &allow-other-keys was specified in the lambda-list.
-
- * Somewhere among the keyword argument pairs is a pair whose keyword is
- :allow-other-keys and whose value is not nil.
-
- If either condition obtains, then it is not an error for an argument pair to
- match no parameter specified, and the argument pair is simply ignored (but such
- an argument pair is accessible through the &rest parameter if one was
- specified). The purpose of these mechanisms is to allow sharing of argument
- lists among several functions and to allow either the caller or the called
- function to specify that such sharing may be taking place.
-
- After all parameter specifiers have been processed, the auxiliary variable
- specifiers (those following the lambda-list keyword &aux) are processed from
- left to right. For each one, the initform is evaluated and the variable var
- bound to that value (or to nil if no initform was specified). Nothing can be
- done with &aux variables that cannot be done with the special form let*:
-
- (lambda (x y &aux (a (car x)) (b 2) c) ...)
- == (lambda (x y) (let* ((a (car x)) (b 2) c) ...))
-
- Which to use is purely a matter of style.
-
- Whenever any initform is evaluated for any parameter specifier, that form may
- refer to any parameter variable to the left of the specifier in which the
- initform appears, including any supplied-p variables, and may rely on the fact
- that no other parameter variable has yet been bound (including its own
- parameter variable).
-
- Once the lambda-list has been processed, the forms in the body of the
- lambda-expression are executed. These forms may refer to the arguments to the
- function by using the names of the parameters. On exit from the function,
- either by a normal return of the function's value(s) or by a non-local exit,
- the parameter bindings, whether lexical or special, are no longer in effect.
- (The bindings are not necessarily permanently discarded, for a lexical binding
- can later be reinstated if a ``closure'' over that binding was created, perhaps
- by using function, and saved before the exit occurred.)
-
- Examples of &optional and &rest parameters:
-
- ((lambda (a b) (+ a (* b 3))) 4 5) => 19
- ((lambda (a &optional (b 2)) (+ a (* b 3))) 4 5) => 19
- ((lambda (a &optional (b 2)) (+ a (* b 3))) 4) => 10
- ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x)))
- => (2 nil 3 nil nil)
- ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x))
- 6)
- => (6 t 3 nil nil)
- ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x))
- 6 3)
- => (6 t 3 t nil)
- ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x))
- 6 3 8)
- => (6 t 3 t (8))
- ((lambda (&optional (a 2 b) (c 3 d) &rest x) (list a b c d x))
- 6 3 8 9 10 11)
- => (6 t 3 t (8 9 10 11))
-
- Examples of &key parameters:
-
- ((lambda (a b &key c d) (list a b c d)) 1 2)
- => (1 2 nil nil)
- ((lambda (a b &key c d) (list a b c d)) 1 2 :c 6)
- => (1 2 6 nil)
- ((lambda (a b &key c d) (list a b c d)) 1 2 :d 8)
- => (1 2 nil 8)
- ((lambda (a b &key c d) (list a b c d)) 1 2 :c 6 :d 8)
- => (1 2 6 8)
- ((lambda (a b &key c d) (list a b c d)) 1 2 :d 8 :c 6)
- => (1 2 6 8)
- ((lambda (a b &key c d) (list a b c d)) :a 1 :d 8 :c 6)
- => (:a 1 6 8)
- ((lambda (a b &key c d) (list a b c d)) :a :b :c :d)
- => (:a :b :d nil)
-
- Examples of mixtures:
-
- ((lambda (a &optional (b 3) &rest x &key c (d a))
- (list a b c d x))
- 1) => (1 3 nil 1 ())
-
- ((lambda (a &optional (b 3) &rest x &key c (d a))
- (list a b c d x))
- 1 2) => (1 2 nil 1 ())
-
- ((lambda (a &optional (b 3) &rest x &key c (d a))
- (list a b c d x))
- :c 7) => (:c 7 nil :c ())
-
- ((lambda (a &optional (b 3) &rest x &key c (d a))
- (list a b c d x))
- 1 6 :c 7) => (1 6 7 1 (:c 7))
-
- ((lambda (a &optional (b 3) &rest x &key c (d a))
- (list a b c d x))
- 1 6 :d 8) => (1 6 nil 8 (:d 8))
-
- ((lambda (a &optional (b 3) &rest x &key c (d a))
- (list a b c d x))
- 1 6 :d 8 :c 9 :d 10) => (1 6 9 8 (:d 8 :c 9 :d 10))
-
- All lambda-list keywords are permitted, but not terribly useful, in
- lambda-expressions appearing explicitly as the first element of a function-call
- form. They are extremely useful, however, in functions given global names by
- defun.
-
- All symbols whose names begin with & are conventionally reserved for use as
- lambda-list keywords and should not be used as variable names. Implementations
- of Common Lisp are free to provide additional lambda-list keywords.
-
- [Constant]
- lambda-list-keywords
-
- The value of lambda-list-keywords is a list of all the lambda-list keywords
- used in the implementation, including the additional ones used only by
- defmacro. This list must contain at least the symbols &optional, &rest, &key,
- &allow-other-keys, &aux, &body, &whole, and &environment.
-
- As an example of the use of &allow-other-keys and :allow-other-keys, consider a
- function that takes two keyword arguments of its own and also accepts
- additional keyword arguments to be passed to make-array:
-
- (defun array-of-strings (str dims &rest keyword-pairs
- &key (start 0) end &allow-other-keys)
- (apply #'make-array dims
- :initial-element (subseq str start end)
- :allow-other-keys t
- keyword-pairs))
-
- This function takes a string and dimensioning information and returns an array
- of the specified dimensions, each of whose elements is the specified string.
- However, :start and :end keyword arguments may be used in the usual manner (see
- chapter 14) to specify that a substring of the given string should be used. In
- addition, the presence of &allow-other-keys in the lambda-list indicates that
- the caller may specify additional keyword arguments; the &rest argument
- provides access to them. These additional keyword arguments are fed to
- make-array. Now, make-array normally does not allow the keywords :start and
- :end to be used, and it would be an error to specify such keyword arguments to
- make-array. However, the presence in the call to make-array of the keyword
- argument :allow-other-keys with a non-nil value causes any extraneous keyword
- arguments, including :start and :end, to be acceptable and ignored.
-
- [Constant]
- lambda-parameters-limit
-
- The value of lambda-parameters-limit is a positive integer that is the upper
- exclusive bound on the number of distinct parameter names that may appear in a
- single lambda-list. This bound depends on the implementation but will not be
- smaller than 50. Implementors are encouraged to make this limit as large as
- practicable without sacrificing performance. See call-arguments-limit.
-
- -------------------------------------------------------------------------------
-
- 5.3. Top-Level Forms
-
- The standard way for the user to interact with a Common Lisp implementation is
- via a read-eval-print loop: the system repeatedly reads a form from some input
- source (such as a keyboard or a disk file), evaluates it, and then prints the
- value(s) to some output sink (such as a display screen or another disk file).
- Any form (evaluable data object) is acceptable; however, certain special forms
- are specifically designed to be convenient for use as top-level forms, rather
- than as forms embedded within other forms in the way that (+ 3 4) is embedded
- within (if p (+ 3 4) 6). These top-level special forms may be used to define
- globally named functions, to define macros, to make declarations, and to define
- global values for special variables.
-
- [old_change_begin]
- It is not illegal to use these forms at other than top level, but whether it is
- meaningful to do so depends on context. Compilers, for example, may not
- recognize these forms properly in other than top-level contexts. (As a special
- case, however, if a progn form appears at top level, then all forms within that
- progn are considered by the compiler to be top-level forms.)
- [old_change_end]
-
- [change_begin]
- X3J13 voted in March 1989 (DEFINING-MACROS-NON-TOP-LEVEL) to clarify that,
- while defining forms normally appear at top level, it is meaningful to place
- them in non-top-level contexts. All defining forms that create functional
- objects from code appearing as argument forms must ensure that such argument
- forms refer to the enclosing lexical environment. Compilers must handle
- defining forms properly in all situations, not just top-level contexts.
- However, certain compile-time side effects of these defining forms are
- performed only when the defining forms occur at top level (see section 25.1).
- [change_end]
-
- -------------------------------------------------------------------------------
- Compatibility note: In MacLisp, a top-level progn is considered to contain
- top-level forms only if the first form is (quote compile). This odd marker is
- unnecessary in Common Lisp.
- -------------------------------------------------------------------------------
-
- Macros are usually defined by using the special form defmacro. This facility is
- fairly complicated; it is described in chapter 8.
-
- -------------------------------------------------------------------------------
-
- * Defining Named Functions
- * Declaring Global Variables and Named Constants
- * Control of Time of Evaluation
-
- -------------------------------------------------------------------------------
-
- 5.3.1. Defining Named Functions
-
- The defun special form is the usual means of defining named functions.
-
- [Macro]
- defun name lambda-list [[ {declaration}* | doc-string ]] {form}*
-
- Evaluating a defun form causes the symbol name to be a global name for the
- function specified by the lambda-expression
-
- (lambda lambda-list {declaration | doc-string}* {form}*)
-
- defined in the lexical environment in which the defun form was executed.
- Because defun forms normally appear at top level, this is normally the null
- lexical environment.
-
- [change_begin]
- X3J13 voted in March 1989 (DEFINING-MACROS-NON-TOP-LEVEL) to clarify that,
- while defining forms normally appear at top level, it is meaningful to place
- them in non-top-level contexts; defun must define the function within the
- enclosing lexical environment, not within the null lexical environment.
-
- X3J13 voted in March 1989 (FUNCTION-NAME) to extend defun to accept any
- function-name (a symbol or a list whose car is setf - see section 7.1) as a
- name. Thus one may write
-
- (defun (setf cadr) ...)
-
- to define a setf expansion function for cadr (although it may be much more
- convenient to use defsetf or define-modify-macro).
- [change_end]
-
- If the optional documentation string doc-string is present, then it is attached
- to the name as a documentation string of type function; see documentation. If
- doc-string is not followed by a declaration, it may be present only if at least
- one form is also specified, as it is otherwise taken to be a form. It is an
- error if more than one doc-string is present.
-
- The forms constitute the body of the defined function; they are executed as an
- implicit progn.
-
- The body of the defined function is implicitly enclosed in a block construct
- whose name is the same as the name of the function. Therefore return-from may
- be used to exit from the function.
-
- Other implementation-dependent bookkeeping actions may be taken as well by
- defun. The name is returned as the value of the defun form. For example:
-
- (defun discriminant (a b c)
- (declare (number a b c))
- "Compute the discriminant for a quadratic equation.
- Given a, b, and c, the value b^2-4*a*c is calculated.
- The quadratic equation a*x^2+b*x+c=0 has real, multiple,
- or complex roots depending on whether this calculated
- value is positive, zero, or negative, respectively."
- (- (* b b) (* 4 a c)))
- => discriminant
- and now (discriminant 1 2/3 -2) => 76/9
-
- [change_begin]
- The documentation string in this example neglects to mention that the
- coefficients a, b, and c must be real for the discrimination criterion to hold.
- Here is an improved version:
-
- "Compute the discriminant for a quadratic equation.
- Given a, b, and c, the value b^2-4*a*c is calculated.
- If the coefficients a, b, and c are all real (that is,
- not complex), then the quadratic equation a*x^2+b*x+c=0
- has real, multiple, or complex roots depending on
- whether this calculated value is positive, zero, or
- negative, respectively."
- [change_end]
-
- It is permissible to use defun to redefine a function, to install a corrected
- version of an incorrect definition, for example. It is permissible to redefine
- a macro as a function. It is an error to attempt to redefine the name of a
- special form (see table 5-1) as a function.
-
- -------------------------------------------------------------------------------
-
- 5.3.2. Declaring Global Variables and Named Constants
-
- The defvar and defparameter special forms are the usual means of specifying
- globally defined variables. The defconstant special form is used for defining
- named constants.
-
- [Macro]
- defvar name [initial-value [documentation]]
- defparameter name initial-value [documentation]
- defconstant name initial-value [documentation]
-
- defvar is the recommended way to declare the use of a special variable in a
- program.
-
- (defvar variable)
-
- proclaims variable to be special (see proclaim), and may perform other
- system-dependent bookkeeping actions.
-
- [change_begin]
- X3J13 voted in June 1987 (DEFVAR-INITIALIZATION) to clarify that if no
- initial-value form is provided, defvar does not change the value of the
- variable; if no initial-value form is provided and the variable has no value,
- defvar does not give it a value.
- [change_end]
-
- If a second argument form is supplied,
-
- (defvar variable initial-value)
-
- then variable is initialized to the result of evaluating the form initial-value
- unless it already has a value. The initial-value form is not evaluated unless
- it is used; this fact is useful if evaluation of the initial-value form does
- something expensive like creating a large data structure.
-
- [change_begin]
- X3J13 voted in June 1987 (DEFVAR-INIT-TIME) to clarify that evaluation of the
- initial-value and the initialization of the variable occur, if at all, at the
- time the defvar form is executed, and that the initial-value form is evaluated
- if and only if the variable does not already have a value.
- [change_end]
-
- The initialization is performed by assignment and thus assigns a global value
- to the variable unless there are currently special bindings of that variable.
- Normally there should not be any such special bindings.
-
- defvar also provides a good place to put a comment describing the meaning of
- the variable, whereas an ordinary special proclamation offers the temptation to
- declare several variables at once and not have room to describe them all.
-
- (defvar *visible-windows* 0
- "Number of windows at least partially visible on the screen")
-
- defparameter is similar to defvar, but defparameter requires an initial-value
- form, always evaluates the form, and assigns the result to the variable. The
- semantic distinction is that defvar is intended to declare a variable changed
- by the program, whereas defparameter is intended to declare a variable that is
- normally constant but can be changed (possibly at run time), where such a
- change is considered a change to the program. defparameter therefore does not
- indicate that the quantity never changes; in particular, it does not license
- the compiler to build assumptions about the value into programs being compiled.
-
- defconstant is like defparameter but does assert that the value of the variable
- name is fixed and does license the compiler to build assumptions about the
- value into programs being compiled. (However, if the compiler chooses to
- replace references to the name of the constant by the value of the constant in
- code to be compiled, perhaps in order to allow further optimization, the
- compiler must take care that such ``copies'' appear to be eql to the object
- that is the actual value of the constant. For example, the compiler may freely
- make copies of numbers but must exercise care when the value is a list.)
-
- It is an error if there are any special bindings of the variable at the time
- the defconstant form is executed (but implementations may or may not check for
- this).
-
- Once a name has been declared by defconstant to be constant, any further
- assignment to or binding of that special variable is an error. This is the case
- for such system-supplied constants as t and most-positive-fixnum. A compiler
- may also choose to issue warnings about bindings of the lexical variable of the
- same name.
-
- [change_begin]
- X3J13 voted in January 1989 (DEFCONSTANT-SPECIAL) to clarify the preceding
- paragraph by specifying that it is an error to rebind constant symbols as
- either lexical or special variables. Consequently, a valid reference to a
- symbol declared with defconstant always refers to its global value.
- (Unfortunately, this violates the principle of referential transparency, for
- one cannot always choose names for lexical variables without regard to
- surrounding context.)
- [change_end]
-
- For any of these constructs, the documentation should be a string. The string
- is attached to the name of the variable, parameter, or constant under the
- variable documentation type; see the documentation function.
-
- [change_begin]
- X3J13 voted in March 1988 (DEFVAR-DOCUMENTATION) to clarify that the
- documentation-string is not evaluated but must appear as a literal string when
- the defvar, defparameter, or defconstant form is evaluated.
-
- For example, the form
-
- (defvar *avoid-registers* nil "Compilation control switch #43")
-
- is legitimate, but
-
- (defvar *avoid-registers* nil
- (format nil "Compilation control switch #~D"
- (incf *compiler-switch-number*)))
-
- is erroneous because the call to format is not a literal string.
-
- (On the other hand, the form
-
- (defvar *avoid-registers* nil
- #.(format nil "Compilation control switch #~D"
- (incf *compiler-switch-number*)))
-
- might be used to accomplish the same purpose, because the call to format is
- evaluated at read time; when the defvar form is evaluated, only the result of
- the call to format, a string, appears in the defvar form.)
- [change_end]
-
- These constructs are normally used only as top-level forms. The value returned
- by each of these constructs is the name declared.
-
- -------------------------------------------------------------------------------
-
- 5.3.3. Control of Time of Evaluation
-
- [old_change_begin]
- The eval-when special form allows pieces of code to be executed only at compile
- time, only at load time, or when interpreted but not compiled. Its uses are
- relatively esoteric.
-
- [Special Form]
- eval-when ({situation}*) {form}*
-
- The body of an eval-when form is processed as an implicit progn, but only in
- the situations listed. Each situation must be a symbol, either compile, load,
- or eval.
-
- eval specifies that the interpreter should process the body. compile specifies
- that the compiler should evaluate the body at compile time in the compilation
- context. load specifies that the compiler should arrange to evaluate the forms
- in the body when the compiled file containing the eval-when form is loaded.
-
- The eval-when construct may be more precisely understood in terms of a model of
- how the compiler processes forms in a file to be compiled. Successive forms are
- read from the file using the function read. These top-level forms are normally
- processed in what we shall call not-compile-time mode. There is another mode
- called compile-time-too mode. The eval-when special form controls which of
- these two modes to use.
-
- Every form is processed as follows:
-
- * If the form is an eval-when form:
-
- o If the situation load is specified:
-
- + If the situation compile is specified, or if the current
- processing mode is compile-time-too and the situation eval is
- specified, then process each of the forms in the body in
- compile-time-too mode.
-
- + Otherwise, process each of the forms in the body in
- not-compile-time mode.
-
- o If the situation load is not specified:
-
- + If the situation compile is specified, or if the current
- processing mode is compile-time-too and the situation eval is
- specified, then evaluate each of the forms in the body in the
- compiler's executing environment.
-
- + Otherwise, ignore the eval-when form entirely.
-
- * If the form is not an eval-when form, then do two things. First, if the
- current processing mode is compile-time-too mode, evaluate the form in the
- compiler's executing environment. Second, perform normal compiler
- processing of the form (compiling functions defined by defun forms, and so
- on).
-
- One example of the use of eval-when is that if the compiler is to be able to
- properly read a file that uses user-defined reader macro characters, it is
- necessary to write
-
- (eval-when (compile load eval)
- (set-macro-character #\$ #'(lambda (stream char)
- (declare (ignore char))
- (list 'dollar (read stream)))))
-
- This causes the call to set-macro-character to be executed in the compiler's
- execution environment, thereby modifying its reader syntax table.
- [old_change_end]
-
- [change_begin]
- X3J13 voted in March 1989 (EVAL-WHEN-NON-TOP-LEVEL) to completely redesign
- the eval-when construct to solve some problems concerning its treatment in
- other than top-level contexts. The new definition is upward compatible with the
- old definition, but the old keywords are deprecated.
-
- [Special Form]
- eval-when ({situation}*) {form}*
-
- The body of an eval-when form is processed as an implicit progn, but only in
- the situations listed. Each situation must be a symbol, either
- :compile-toplevel, :load-toplevel, or :execute.
-
- The use of :compile-toplevel and :load-toplevel controls whether and when
- processing occurs for top-level forms. The use of :execute controls whether
- processing occurs for non-top-level forms.
-
- The eval-when construct may be more precisely understood in terms of a model of
- how the file compiler, compile-file, processes forms in a file to be compiled.
-
- Successive forms are read from the file by the file compiler using read. These
- top-level forms are normally processed in what we call ``not-compile-time''
- mode. There is one other mode, called ``compile-time-too'' mode, which can come
- into play for top-level forms. The eval-when special form is used to annotate a
- program in a way that allows the program doing the processing to select the
- appropriate mode.
-
- Processing of top-level forms in the file compiler works as follows:
-
- * If the form is a macro call, it is expanded and the result is processed
- as a top-level form in the same processing mode (compile-time-too or
- not-compile-time).
-
- * If the form is a progn (or locally (LOCALLY-TOP-LEVEL) ) form, each of
- its body forms is sequentially processed as top-level forms in the same
- processing mode.
-
- * If the form is a compiler-let, macrolet, or symbol-macrolet, the file
- compiler makes the appropriate bindings and recursively processes the body
- forms as an implicit top-level progn with those bindings in effect, in the
- same processing mode.
-
- * If the form is an eval-when form, it is handled according to the
- following table:
-
-
-
- In the preceding table the column LT asks whether :load-toplevel is one of
- the situations specified in the eval-when form; CT similarly refers to
- :compile-toplevel and EX to :execute. The column CTTM asks whether the
- eval-when form was encountered while in compile-time-too mode. The phrase
- ``process body'' means to process the body as an implicit top-level progn
- in the indicated mode, and ``evaluate body'' means to evaluate the body
- forms sequentially as an implicit progn in the dynamic execution context
- of the compiler and in the lexical environment in which the eval-when
- appears.
-
- * Otherwise, the form is a top-level form that is not one of the special
- cases. If in compile-time-too mode, the compiler first evaluates the form
- and then performs normal compiler processing on it. If in not-compile-time
- mode, only normal compiler processing is performed (see section 25.1). Any
- subforms are treated as non-top-level forms.
-
- Note that top-level forms are guaranteed to be processed in the order in which
- they textually appear in the file, and that each top-level form read by the
- compiler is processed before the next is read. However, the order of processing
- (including, in particular, macro expansion) of subforms that are not top-level
- forms is unspecified.
-
- For an eval-when form that is not a top-level form in the file compiler (that
- is, either in the interpreter, in compile, or in the file compiler but not at
- top level), if the :execute situation is specified, its body is treated as an
- implicit progn. Otherwise, the body is ignored and the eval-when form has the
- value nil.
-
- For the sake of backward compatibility, a situation may also be compile, load,
- or eval. Within a top-level eval-when form these have the same meaning as
- :compile-toplevel, :load-toplevel, and :execute, respectively; but their effect
- is undefined when used in an eval-when form that is not at top level.
-
- The following effects are logical consequences of the preceding specification:
-
- * It is never the case that the execution of a single eval-when expression
- will execute the body code more than once.
-
- * The old keyword eval was a misnomer because execution of the body need
- not be done by eval. For example, when the function definition
-
- (defun foo () (eval-when (:execute) (print 'foo)))
-
-
- is compiled the call to print should be compiled, not evaluated at compile
- time.
-
- * Macros intended for use in top-level forms should arrange for all
- side-effects to be done by the forms in the macro expansion. The
- macro-expander itself should not perform the side-effects.
-
- (defmacro foo ()
- (really-foo) ;Wrong
- `(really-foo))
-
- (defmacro foo ()
- `(eval-when (:compile-toplevel
- :load-toplevel :execute) ;Right
- (really-foo)))
-
- Adherence to this convention will mean that such macros will behave
- intuitively when called in non-top-level positions.
-
- * Placing a variable binding around an eval-when reliably captures the
- binding because the ``compile-time-too'' mode cannot occur (because the
- eval-when could not be a top-level form). For example,
-
- (let ((x 3))
- (eval-when (:compile-toplevel :load-toplevel :execute)
- (print x)))
-
- will print 3 at execution (that is, load) time and will not print anything
- at compile time. This is important so that expansions of defun and
- defmacro can be done in terms of eval-when and can correctly capture the
- lexical environment. For example, an implementation might expand a defun
- form such as
-
- (defun bar (x) (defun foo () (+ x 3)))
-
- into
-
- (progn (eval-when (:compile-toplevel)
- (compiler::notice-function 'bar '(x)))
- (eval-when (:load-toplevel :execute)
- (setf (symbol-function 'bar)
- #'(lambda (x)
- (progn (eval-when (:compile-toplevel)
- (compiler::notice-function 'foo
- '()))
- (eval-when (:load-toplevel :execute)
- (setf (symbol-function 'foo)
- #'(lambda () (+ x 3)))))))))
-
- which by the preceding rules would be treated the same as
-
- (progn (eval-when (:compile-toplevel)
- (compiler::notice-function 'bar '(x)))
- (eval-when (:load-toplevel :execute)
- (setf (symbol-function 'bar)
- #'(lambda (x)
- (progn (eval-when (:load-toplevel :execute)
- (setf (symbol-function 'foo)
- #'(lambda () (+ x 3)))))))))
-
- Here are some additional examples.
-
- (let ((x 1))
- (eval-when (:execute :load-toplevel :compile-toplevel)
- (setf (symbol-function 'foo1) #'(lambda () x))))
-
- The eval-when in the preceding expression is not at top level, so only the
- :execute keyword is considered. At compile time, this has no effect. At load
- time (if the let is at top level), or at execution time (if the let is embedded
- in some other form which does not execute until later), this sets
- (symbol-function 'foo1) to a function that returns 1.
-
- (eval-when (:execute :load-toplevel :compile-toplevel)
- (let ((x 2))
- (eval-when (:execute :load-toplevel :compile-toplevel)
- (setf (symbol-function 'foo2) #'(lambda () x)))))
-
- If the preceding expression occurs at the top level of a file to be compiled,
- it has both a compile time and a load-time effect of setting (symbol-function
- 'foo2) to a function that returns 2.
-
- (eval-when (:execute :load-toplevel :compile-toplevel)
- (setf (symbol-function 'foo3) #'(lambda () 3)))
-
- If the preceding expression occurs at the top level of a file to be compiled,
- it has both a compile time and a load-time effect of setting the function cell
- of foo3 to a function that returns 3.
-
- (eval-when (:compile-toplevel)
- (eval-when (:compile-toplevel)
- (print 'foo4)))
-
- The preceding expression always does nothing; it simply returns nil.
-
- (eval-when (:compile-toplevel)
- (eval-when (:execute)
- (print 'foo5)))
-
- If the preceding form occurs at the top level of a file to be compiled, foo5 is
- printed at compile time. If this form occurs in a non-top-level position,
- nothing is printed at compile time. Regardless of context, nothing is ever
- printed at load time or execution time.
-
- (eval-when (:execute :load-toplevel)
- (eval-when (:compile-toplevel)
- (print 'foo6)))
-
- If the preceding form occurs at the top level of a file to be compiled, foo6 is
- printed at compile time. If this form occurs in a non-top-level position,
- nothing is printed at compile time. Regardless of context, nothing is ever
- printed at load time or execution time.
-
- [change_end]
-
- -------------------------------------------------------------------------------
-
-
-
-
-
-
-
-
-